package com.wtwd.campus.service.impl;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wtwd.campus.common.RespCode;
import com.wtwd.campus.constant.SignConstant;
import com.wtwd.campus.dao.TeacherMapper;
import com.wtwd.campus.entity.Teacher;
import com.wtwd.campus.model.TeacherExcelImportModel;
import com.wtwd.campus.model.TeacherQueryModel;
import com.wtwd.campus.model.vo.ImportExcelResponseVO;
import com.wtwd.campus.model.vo.ResultVO;
import com.wtwd.campus.model.vo.TeacherVO;
import com.wtwd.campus.service.ClassService;
import com.wtwd.campus.service.TeacherService;
import com.wtwd.campus.utils.MyExcelUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zdl
 * @since 2021-07-08
 */
@Service
public class TeacherServiceImpl implements TeacherService {

    private Logger log = LoggerFactory.getLogger(TeacherServiceImpl.class);

    @Resource
    private TeacherMapper teacherMapper;

    @Resource
    private ClassService classService;

    @Override
    public IPage<TeacherVO> queryPage(Page page, TeacherQueryModel teacherQueryModel) {
        return teacherMapper.queryList(page, teacherQueryModel);
    }

    @Override
    public ResultVO deleteTeacherById(Integer id) {
        teacherMapper.deleteById(id);
        return ResultVO.ok();
    }

    @Override
    public ResultVO createTeacher(Teacher teacher) {
        if (teacher.getSchoolId() == null || teacher.getType() == null
                || StringUtils.isAnyBlank(teacher.getName(), teacher.getPhone())) {
            return ResultVO.error(RespCode.PARAMS_ERROR);
        }
        if (teacher.getManageClass() != null) {
            if (teacher.getType() != 1) return ResultVO.error(RespCode.PARAMS_ERROR);
            if (isExistClassTeacher(teacher.getManageClass())) {
                return ResultVO.error(RespCode.ALREADY_EXISTS_ClASSES_TEACHER);
            }
        }
        try {
            teacherMapper.insert(teacher);
        } catch (DuplicateKeyException e) {
            return ResultVO.error(RespCode.PHONE_EXIST);
        }
        return ResultVO.ok();
    }

    @Override
    public ResultVO updateTeacher(Teacher teacher) {
        if (teacher.getId() == null) {
            return ResultVO.error(RespCode.PARAMS_ERROR);
        }
        if (teacher.getManageClass() != null) {
            Teacher data = new LambdaQueryChainWrapper<>(teacherMapper)
                    .eq(Teacher::getManageClass, 1)
                    .one();
            if (data != null && !teacher.getId().equals(data.getId())) {
                return ResultVO.error(RespCode.ALREADY_EXISTS_ClASSES_TEACHER);
            }
        }
        try {
            teacherMapper.updateById(teacher);
        } catch (DuplicateKeyException e) {
            return ResultVO.error(RespCode.PHONE_EXIST);
        }
        return ResultVO.ok();
    }

    @Override
    public ResultVO insertBatch(List<TeacherVO> teachers) {
        try {
            if(teachers!=null && teachers.size()>0){
                teacherMapper.insertBatch(teachers);
            }

        } catch (DuplicateKeyException e) {
            e.getMessage();
        }
        return ResultVO.ok(teachers);
    }

    @Override
    public ResultVO importByExcel(Integer schoolId, List<TeacherExcelImportModel> teacherModelData) {
        List<TeacherExcelImportModel> importFailData = new ArrayList<>();
        List<TeacherVO> preInsertData = new ArrayList<>();
        HashSet<String> classNameSet = new HashSet<>();
        Map<String, TeacherExcelImportModel> excleMap = new HashMap<>();
        //例：董一	班主任	三年级	一班	  二年级/一班，三年级/二班	13412345678
        AtomicInteger ignoreNum = new AtomicInteger();
        //TODO 检查必填字段
        teacherModelData.forEach(item -> {
            String teacherName = item.getTeacherName();
            String type = item.getType();
            String teachClass = item.getTeachClass();
            String manageGrade = item.getManageGrade();
            String manageClass = item.getManageClass();
            String phone = item.getPhone();
            if (StringUtils.isAnyBlank(teacherName, type, teachClass, phone)) {
                item.setMessage("请检查必填项");
                importFailData.add(item);
                return;
            }
            if (teacherName.startsWith("例：")) {
                ignoreNum.getAndIncrement();
                return;
            }
            boolean isClassManage = "班主任".equalsIgnoreCase(type);
            if (isClassManage && StringUtils.isAnyBlank(manageGrade, manageClass)) {
                item.setMessage("教师为班主任时,代班年级和班级必填");
                importFailData.add(item);
                return;
            }
            if (excleMap.containsKey(phone)) {
                item.setMessage("手机号重复,或格式错误");
                importFailData.add(item);
                return;
            }
            //TODO 添加要获取的年级班级名称
            try {
                for (String s : teachClass.split(SignConstant.ZH_COMMA)) {
                    classNameSet.add(s.split(SignConstant.DELIMITER)[1]);
                }
            } catch (Exception e) {
                item.setMessage("授课班级,格式错误");
                importFailData.add(item);
                return;
            }
            if (isClassManage) {
                classNameSet.add(manageClass);
            }
            //TODO 添加预保存队列
            TeacherVO teacher = new TeacherVO();
            teacher.setSchoolId(schoolId);
            teacher.setName(teacherName);
            teacher.setType(isClassManage ? 1 : 2);
            if (isClassManage) {
                teacher.setManageClassName(String.join(SignConstant.DELIMITER, manageGrade, manageClass));
            }
            teacher.setTeachClass(teachClass);
            teacher.setPhone(phone);
            long now = System.currentTimeMillis();
            teacher.setCreateTime(now);
            teacher.setUpdateTime(now);
            preInsertData.add(teacher);
            excleMap.put(phone, item);

        });
        //TODO 根据学校,班级,年级名称获取班级年级ID
        Map<String, String> classGradeIds = classService.getClassGradeIdByClassNames(schoolId, classNameSet);
        Iterator<TeacherVO> iterator = preInsertData.iterator();
        while (iterator.hasNext()) {
            TeacherVO item = iterator.next();
            try {
                if (1 == item.getType()) {//班主任
                    String[] s = classGradeIds.get(item.getManageClassName()).split(SignConstant.DELIMITER);
                    item.setManageClassGrade(Integer.valueOf(s[0]));
                    item.setManageClass(Integer.valueOf(s[1]));
                }
                String[] s = item.getTeachClass().split(SignConstant.ZH_COMMA);
                LinkedHashSet<String> teachClass = new LinkedHashSet<>();
                LinkedHashSet<String> teachGrade = new LinkedHashSet<>();
                for (String s1 : s) {
                    String[] split = classGradeIds.get(s1).split(SignConstant.DELIMITER);
                    teachGrade.add(split[0]);
                    teachClass.add(split[1]);
                }
                item.setTeachClassGrade(StringUtils.join(teachGrade, SignConstant.COMMA));
                item.setTeachClass(StringUtils.join(teachClass, SignConstant.COMMA));
            } catch (Exception e) {
                //年级或班级不存在
                TeacherExcelImportModel failData = excleMap.get(item.getPhone());
                failData.setMessage("年级或班级不存在");
                importFailData.add(failData);
                iterator.remove();
            }
        }
        ResultVO resultVO = insertBatch(preInsertData);
        ((List<TeacherVO>) resultVO.getData()).forEach(item -> {
            if (item.getId() == null) {
                //保存失败,默认失败原因为手机号重复
                TeacherExcelImportModel failData = excleMap.get(item.getPhone());
                failData.setMessage("手机号重复");
                importFailData.add(failData);
            }
        });
        int failNum = importFailData.size();
        ImportExcelResponseVO responseVO = new ImportExcelResponseVO();
        responseVO.setFailNum(failNum);
        responseVO.setSuccessNum(teacherModelData.size() - failNum - ignoreNum.intValue());
        if (failNum > 0) {
            String path = MyExcelUtils.exportExcel(importFailData, "教师信息", "教师信息", TeacherExcelImportModel.class, "学生文件导入失败信息.xls", null);
            responseVO.setFilePath(path);
        }
        return ResultVO.ok(responseVO);
    }

    @Override
    public Teacher getTeacherByPhone(String phone) {
        return teacherMapper.getTeacherByPhone(phone);
    }

    private boolean isExistClassTeacher(Integer classId) {
        return new LambdaQueryChainWrapper<>(teacherMapper)
                .eq(Teacher::getManageClass, classId)
                .count() > 0;
    }
}
